
CCstl = function() {
	this.objName = 'Cstl: ';
	
	// public members
	this.id = 0;
	this.name = 0;
	this.cds = [];
	this.sols = [];
	this.resbuild = {};
	this.barrac = {};
	this.uni = {};
	this.are = {};		// arena 
	this.dt = {};	// donwtown
	this.res = {};
	this.heroes = [] ;
	this.hntings = [];
	this.att_result = 0;		// success 
};



CCstl.prototype = {
	objName: 'CCstl : ',

	setUserCityInfo: function(info){
		// {"id":3070,"name":"\ucc9c\uc0c1\uc131","landtype":3,"x":185,"y":53},
		$.extend(this, info);
		
	},



/*
	Huntings info 
*/
	// hid, endtime , push into cds  :: same result 임.. 
	addHntingInfo: function(hntinfo) {
		// this.cds.push(hntinfo);
		var self = this;
		var updated = false;
		$.each( this.cds  , function(_, curcd) {
			if ( curcd.id == hntinfo.id )	{	
				// same item  : update 
				 $.extend( curcd, hntinfo);
				 return false;		/// exit each 
			}
		});

		// new one  : already calced  endtime  by hnting
		if( updated == false ) {
			self.cds.push(hntinfo);
		}  

			
		// hid ,: remove doing attckih from  cstl hntings h 에서 제거
		var hindex = CUtil.findIdxArrByProperty(this.hntingalbeHs, hntinfo.h , 'gid');
	
		if ( hindex >= 0){
			this.hntingalbeHs.splice(hindex, 1);
		}
		
		// cost : consume res 
		this.res.f -= hntinfo.cost.cost_food;
		var self = this;
		function solsNum(type) {
			if ( self.sols )
				return self.sols.filter( function(el) { return el[0] == type})[0];
		};
		function minusSol(type, n){
			if ( self.sols && self.sols[type-1])
				self.sols[type-1][1] -= n ? n: 0; 
		};
	// trs : reflect to cstl sols
	// !! Caution !! : type is not index !! should  -1 !!
	if (solsNum(CDB.SOLS.OVER))
		minusSol( CDB.SOLS.OVER, hntinfo.trs.o); 
		
	if (solsNum(CDB.SOLS.BER))
		minusSol(CDB.SOLS.BER , hntinfo.trs.b); 
		
	if (solsNum(CDB.SOLS.HNT))
		minusSol( CDB.SOLS.HNT, hntinfo.trs.h); 
		
	if (solsNum(CDB.SOLS.SPY))
		minusSol(CDB.SOLS.SPY , hntinfo.trs.s);
		 
	if (solsNum(CDB.SOLS.KAKL))
		minusSol( CDB.SOLS.KAKL , hntinfo.trs.k); 
		
	if (solsNum(CDB.SOLS.CARRIER))
		minusSol(CDB.SOLS.CARRIER , hntinfo.trs.c); 
		
	if (solsNum(CDB.SOLS.LANU))
		minusSol( CDB.SOLS.LANU , hntinfo.trs.l); 
		
	},

	setAttResult: function(ret) {
		this.att_result = ret;
	},
	
	getAttResult: function() {
		return this.att_result;
	},
	// clear (delete) old hnt time.  compare with cur time ; 
/*
	clearExpireHnting: function() {
		if ( this.hntings.length == 0) 
			return;
			
		var now = $.now();
		var temp = this.hntings.slice(0);
		this.hntings = [];	// clear 
		
		var self = this;
		$.each( temp, function(_, hnt) {
			if ( hnt.endtime.getTime() > now) {
				self.hntings.push(hnt);	
			}
		});
	},*/

			
/*
	resetHntings: function(){
		this.hntings = [];
	},*/

	
	// return cdtype  4  ( hnting )  both after hnting  & move cstl 
	getHntings: function ()	{
		
/*		:: move to cstl mgr 
		// clear hnting cds 
		this.cds = this.clearExpireItems(this.cds, 4);		// clear 4 hnting type
*/
		
		if ( this.cds === undefined) {
			this.cds = []; 
		}
		var cds = this.cds
		 
		var curHntings = cds.filter( function (cd){
			debug.log( this, 'cd :' , cd);
			if (cd.cdtype == 4) return true; 
			return false;
		}) ;
		
		// 원본에서 cd === 4 를 제거 하도록 변경. 
		// var curHntings = this.clearExpireItems(hntings);
		debug.log( this, 'curHntings: ' , curHntings);
		return curHntings;
	},
	
	// cleared by cstl mgr  when  expired hnt cd is processed
	clearExpiredHntings: function() {
		this.cds = this.clearExpireItems(this.cds, 4);		// clear 4 hnting type
	},
	
	
	updateRes: function(res) {
		$.extend( this.res, res); // w, g, i , f
	},


/*
	SOLS  ===========================================
*/
	updateSols: function(sols){
		this.sols = sols; // sol array 
	},
	
	getSols: function() {
		return this.sols;
	},
	
	getSolnum: function(type) {
		var tr = this.sols ? this.sols.filter( function(el) { return el[0] == type})[0] : undefined;
		return tr ? tr[1] : 0;
	},
	
	
	/*
		CDS ==============
	*/
	
	// endtime add automatically 
	updateCdlist: function(cds) {
		// sec 를 이용 endtime 계산,
		var self  = this;
		
		$.each( cds, function(_,cd){
			//
			// check incoming loot 
			
			if ( cd.cdtype == 5 ) {
				alert( 'Incoming Loot' + cd.ext + ' t:  ' + cd.target  + ' o:' + cd.owner);
			}
			// 2 case   : after att
			// {"code":0,"ret":{"cd":[{"id":3321647,"cdtype":4,"target":7,"owner":185,"secs":300,"ret":0,"ext":"204\/251"}]}}
			// after move cstl 
			// 						  {"id":3432845,"cdtype":4,"target":7,"owner":71,"secs":29,"ret":0,"ext":"147\/63"}]
			var updated = false;
			$.each( self.cds  , function(_, curcd) {
				if ( curcd.id == cd.id )	{	
					 
					 // when use fast tem :  check secs : endtime
					 // adust endtime  
					 if ( cd.secs <  curcd.secs ) {
					 	if ( curcd.endtime ) delete curcd.endtime;
					 	curcd.endtime = new Date($.now() + cd.secs * 1000);
					 } 
/*
					// same item  : update 
					if ( cd.secs < curcd.secs ) {
						if (curcd.endtime ) delete curcd.endtime;
						curcd.endtime = new Date($.now() + cd.secs * 1000);
					}*/

					 $.extend( curcd, cd);

					 updated = true;
					 return false; // exit each 
				} 
			});
			
			// new one  : calc endtime and insert
			if ( updated == false ) {
				if ( !cd.endtime)
					cd.endtime = new Date($.now() + cd.secs * 1000);
				self.cds.push(cd);
			} 
		});
	
	},
	
	// cd 
	// cd type : 2 : build,   1: 연속 로긴 건설.  0: 10랩 보호. 
	// cd target : 5  barrack   , 9 : 연속 로긴. 
	getCds: function(){

		// this.cds = this.clearExpireItems(this.cds);
		// debug.log(this, ' getCds : ', this.cds);
		return this.cds;
	},
	
		// find .  wanted cds . 
	findCds: function(type, target) {
		
		var this_cds = this.cds.filter( function( el) {
					return el.cdtype == type && el.target == target; 
		});
		
		debug.log(this, 'findCds  :', this_cds);
		return this_cds;		
	},
		// find .  wanted cds . 
	findCdTypes: function(type) {
		var this_cds = this.cds.filter( function( el) {
					return el.cdtype == type; 
		});
		
		debug.log(this, 'findCds  :', this_cds);
		return this_cds;		
	},
	
	// clear expired cd :  by type 
	clearExpired: function(type) {
		this.cds = this.clearExpireItems(this.cds, type);
		
		debug.log(this, 'remains  :', this.cds);
		return this.cds;		
	},
	
	/*
		 Cit info  =========
	*/
	updateCityInfo: function(info){
				/*

2 : remain area
192 : area
484741,21213527,2915768,21213527,220137,21213527,1075887,21213527,  : resource  cur / max
9652,9644, : popul
5,5,5,29, :  farm
18,26,24,22,13,24,18,  : structure   town, bar, wall, arena, storage,  research, fucility


{"city":
[2,193,
	484741,21213527,2915768,21213527,220137,21213527,1075887,21213527, //9
	9652,9644, 	//11
	5,5,5,29,		//15
	18,26,24,22,13,24,18,   // 22    uni : 21,  town : 20 , fucil : 22 
	[{"id":39545,"itemid":166,"secs":118075}, //23
		{"id":40536,"itemid":166,"secs":462108},
		{"id":40819,"itemid":120,"secs":45057}]
	,0],
	
"grade":62,"money":0}
}
		*/
		
		// �쇰떒 �꾩껜 ��옣.
		this.city = info; 
		 
		// �섎㉧吏��꾩슂��寃껋� property 濡���옣.
		this.popul = info[10];
		this.popul_max = info[11];
		
		this.resbuild.farm = info[15];
		this.dt.town = info[16];
		this.barrac.lv = info[17];
		this.wall = info[18]	;
		this.are.lv = info[19];
		this.uni.lv = [21];
		this.dt.fuci = info[22]	;
		
/*
		var city_res = {g: data.ret.city[2] ,
						f: data.ret.city[4] , 
						w: data.ret.city[6] , 
						i: data.ret.city[8]  };*/

		//this.res = info.slice(2,9);

		var res = {"f":info[4],"w":info[6],"i":info[8],"g":info[2]} ;
		$.extend(this.res, res);
		//$.extend(this, info);
		debug.log(this, 'cstl: ', this);

		
	},
	
	getBlessCnt: function() {
			var bufs  = this.city[23]
			var buf_cnt = 0;
			$.each (  bufs , function(i, b) {
				if ( b.itemid == 166 || b.itemid == 167 ) {
					buf_cnt++;
				}
			});
			return buf_cnt;
	},
	// make arr of blds .
	// return bld arr  [  [name, lv, type] , []] 
	getBlds: function() {
		this.blds = [];
		var self = this;
		$.each( CDB.BUILD , function (i, bld) {
								// name, lv, type 
				self.blds.push( [ bld.name , self.city[ bld.pos ] , bld.type ] );
			} );
		return this.blds;
	},
	
	getBldLv: function( bld_obj ) {
			return this.city[ bld_obj.pos ];
	},
	
	
	
	// "cdtype":4
	bIsHnting: function() {
		var hnting = false;
		$.each ( this.cds, function(_, cd) {
			if ( cd.cdtype == 4 ) {
				hnting = true;
				return false;	//break loop 
			}
		});
		return hnting;
	},
	
	
	/*
		Heroes  ================================
	*/
	
	findh: function(h) {
		// if ( ! this.heroes ) return undefined;
		var i;
		for ( i=0; i < this.heroes.length; i++ ) {
			if ( h.id == this.heroes[i].id){
				return this.heroes[i];
			} 
		}
		if ( i == this.heroes.length) {
			// not found
			debug.log(this, 3, "Not Found H : " + h.id); 
			return undefined;
		}
	},

	updateHF: function(h, f) {
		var hh = this.findh(h);
		if (hh) {
			$.extend( hh, h);
			hh.f = f;
		}
	},
	
	updateHntingableHs : function(hs) {
		debug.log(this, ' Update updateHntingableHs : ' , hs);
		// update heroes list 
		this.hntingalbeHs = hs;		
	},
	
	// from after cstl, arena,  from fealty arena 
	updateAllHs: function(hs) {
		debug.log(this, ' Update updateAllHs : ' , hs);
		this.heroes = hs;
		this.hntingalbeHs = this.getAvailHs();
	},
	
	// s : work type,  e : vigor   check  
	getAvailHs: function() {
// 		 "s":5,"e":9,
		return this.heroes.filter( function(h) {
				return ( h.s == 0 && h.e > 0);
			} );
	},
	
	//  return h with max controlls 
	getbestH: function() {
			// sort  with max control 
		var availHs = this.hntingalbeHs;
		availHs.sort(function (a,b) { 
				return b.c2 - a.c2; });
		
		// except speical A h 
			// check if exist only war hero
			var chooseH = 0;
			// TODO :  A h  gid 파악..     
			while ( availHs[chooseH] &&
				// when pvp .. need tani 
				( !CDB.getCurUserOptions().pvp && availHs[chooseH].g >= 19 ) 
				 ) {
				chooseH++;
				if ( chooseH >= availHs.length ) {
					debug.log( this, "no HHHHHero remains less than lv 19 hero  ");
					return undefined;
				}
			}
 		
		return availHs[chooseH];
	},
	
	
	/*
		studies ===============
	*/
	 // {"code":0,"ret":[[1,1,1],[2,1,1],[3,0,1]],"ext":[4,4]};
	updateStudies: function(studies) {
		debug.log(this, ' Update updateStudies  : ' , studies);
		// update heroes list 
		this.studies = studies;		
	},
	
	getStudyLv: function( s_obj ) {
		return this.studies[ s_obj.pos ] !== undefined ?  this.studies[ s_obj.pos ][1] : 0;
	},
	
	/*
		addtional info
	*/
/*
	 UTIL funciton ===========
*/

	// remove itself elements when endtime is expired  and type is matched  
	clearExpireItems: function( arr , type) {
		if ( arr.length == 0) 
			return [];
		
		var  bAllclear = (type == undefined ) ? true: false; 
		var now = $.now();
		var temp = arr.slice(0);
		// debug.log(this, ' clear :  ori', now, arr , 'ori len:', arr.length	);
		
		// clear old arr
		while( arr.length > 0) arr.pop();
		 
		
		var self = this;
		$.each( temp, function(_, item) {
			// debug.log(this, ' item : ', item.endtime.getTime() - now, 'cdtype', item.cdtype, item );
			
			// 남길 거 선택 
			
			// type 없다면, 시간 큰거만,  
			// type 있다면, 일치 하고, 큰거, or  type 다른거. 
			if ( ( bAllclear &&  item.endtime && item.endtime.getTime() > now ) 
					|| ( type && 
						(
						( type == item.cdtype && item.endtime && item.endtime.getTime() > now )
						 || type != item.cdtype ) )
						) {
						
			// if ( item.endtime && item.endtime.getTime() > now && 
					 // (  type == item.cdtype  || bAllclear ) ) {		// type  check
				// debug.log(this, ' push : ', item );
				arr.push(item);	
			}
		});
		// debug.log(this, ' After cleared', arr , ' after cleared len:', arr.length	);
		if ( arr === undefined ) return [];
		return arr;
	},
};

